package com.dragon.logical.service.contract.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.model.ResultCode;
import com.dragon.common.model.exception.CustomException;
import com.dragon.logical.service.contract.IEquipmentService;
import com.dragon.logical.service.contract.ISchedulingOutService;
import com.dragon.repository.entity.*;
import com.dragon.repository.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 外发 服务实现类
 * </p>
 *
 * @author sy
 * @since 2023-11-29
 */
@Service
public class SchedulingOutServiceImpl extends ServiceImpl<SchedulingOutMapper, SchedulingOut> implements ISchedulingOutService {

    @Autowired
    SchedulingOutMapper schedulingOutMapper;
    @Autowired
    ProduceProductsMapper produceProductsMapper;
    @Autowired
    IEquipmentService equipmentService;
    @Autowired
    SchedulingOutSonMapper outSonMapper;
    @Autowired
    ProduceMapper produceMapper;
    @Autowired
    RejectedMapper rejectedMapper;
    @Autowired
    RejectedProductMapper rejectedProductMapper;
    @Autowired
    VendorMapper vendorMapper;
    @Autowired
    VendorBillSonMapper vendorBillSonMapper;


    @Override
    public Page<SchedulingOut> schedulingOutList(Integer page, Integer limit, Integer type, String search) {
        Page<SchedulingOut> schedulingOutPage = new Page<>(page, limit);
        QueryWrapper<SchedulingOut> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(type != null,SchedulingOut::getType, type)
                .like(StrUtil.isNotBlank(search), SchedulingOut::getVendorName, search)
                .orderByDesc(SchedulingOut::getCreateTime);
        Page<SchedulingOut> outPage = schedulingOutMapper.selectPageWrapper(schedulingOutPage, wrapper);
        outPage.getRecords().forEach(schedulingOut -> {
            List<SchedulingOutSon> outSonList = outSonMapper.selectListByOutId(schedulingOut.getId());
            schedulingOut.setSchedulingOutSonList(outSonList);
        });
        return outPage;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void schedulingOutAdd(SchedulingOut schedulingOut){
        //添加主表
        schedulingOut.setCreateTime(DateUtil.date());
        schedulingOut.setType(1);
        schedulingOutMapper.insert(schedulingOut);
        //添加 供应商账单子表
        VendorBillSon vendorBillSon = new VendorBillSon();
        vendorBillSon.setVendorId(Integer.valueOf(schedulingOut.getSupplierId()));
        vendorBillSon.setOutMoney(schedulingOut.getMoney());
        vendorBillSon.setCreateTime(schedulingOut.getCreateTime());
        vendorBillSon.setSchedulingOutId(schedulingOut.getId());
        vendorBillSonMapper.insert(vendorBillSon);

        List<Integer> idList = Stream.of(schedulingOut.getProduceId().split(","))
                .map(Integer::valueOf).collect(Collectors.toList());
        idList.forEach(produceId -> {
            Produce produce = produceMapper.selectById(produceId);
            if(produce.getType() == 0){
                produce.setType(1);
                produceMapper.updateById(produce);
            }
        });
        schedulingOut.getSchedulingOutSonList().forEach(schedulingOutSon -> {
            //生产产品表修改
            QueryWrapper<ProduceProducts> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(ProduceProducts::getProduceId,schedulingOutSon.getProduceId())
                    .eq(ProduceProducts::getQuotesProductId,schedulingOutSon.getProductId());
            ProduceProducts produceProducts = produceProductsMapper.selectOne(wrapper);
            if(produceProducts.getNum().equals(produceProducts.getScheduledNum())){
                //执行下一次循环
                throw new CustomException(ResultCode.SCHEDULING_OUT_NUM_INADEQUATE);
            }
            produceProducts.setProduceStatus(1);
            produceProducts.setIsOut(1);
            produceProducts.setScheduledNum( produceProducts.getScheduledNum() + schedulingOutSon.getSchedulingNum() );
            if (produceProducts.getNum() <= produceProducts.getScheduledNum()){
                produceProducts.setSchedulingStatus(2);
            } else {
                produceProducts.setSchedulingStatus(1);
            }
            produceProductsMapper.updateById(produceProducts);

            //添加子表
            schedulingOutSon.setCreateTime(DateUtil.date());
            schedulingOutSon.setType(1);
            schedulingOutSon.setSchedulingOutId(schedulingOut.getId());
            outSonMapper.insert(schedulingOutSon);

            //判断生产单是否 从退货来
            Produce produce = produceMapper.selectById(schedulingOutSon.getProduceId());
            if (produce.getSource() == 1){
                //修改 退货产品中的 已处理数量
                Rejected rejected = rejectedMapper.selectById(produce.getRejectedId());
                QueryWrapper<RejectedProduct> wrapper1 = new QueryWrapper<>();
                wrapper1.lambda().eq(RejectedProduct::getRejectedId,rejected.getId())
                        .eq(RejectedProduct::getProductId,schedulingOutSon.getProductId());
                RejectedProduct rejectedProduct = rejectedProductMapper.selectOne(wrapper1);
                int processNum = rejectedProduct.getProcessingNum() + schedulingOutSon.getSchedulingNum();
                //添加正在处理的数量
                rejectedProduct.setProcessingNum( processNum );
                rejectedProductMapper.updateById(rejectedProduct);
            }
        });

        List<Integer> ids = Stream.of(schedulingOut.getProduceId().split(",")).map(Integer::valueOf).collect(Collectors.toList());
        ids.forEach(produceId->{
            equipmentService.updateProduceType(produceId);
        });

    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void enterDateOut(SchedulingOut schedulingOut) {
        //获取外发信息
        SchedulingOut schedulingOut1 = schedulingOutMapper.selectById(schedulingOut.getId());
        if (schedulingOut1 == null){
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        schedulingOut1.setType(2);
        schedulingOut1.setUpdateTime(DateUtil.date());
        schedulingOutMapper.updateById(schedulingOut1);
        //获取外发子表
        List<SchedulingOutSon> outSonList = outSonMapper.selectListByOutId(schedulingOut.getId());
        outSonList.forEach(schedulingOutSon -> {

            //生产产品表修改
            QueryWrapper<ProduceProducts> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(ProduceProducts::getProduceId,schedulingOutSon.getProduceId())
                    .eq(ProduceProducts::getQuotesProductId,schedulingOutSon.getProductId());
            ProduceProducts produceProducts = produceProductsMapper.selectOne(wrapper);
            produceProducts.setProduceNum( produceProducts.getProduceNum() + schedulingOutSon.getSchedulingNum() );
            produceProducts.setUpdateTime(DateUtil.date());
            if (produceProducts.getNum() <= produceProducts.getProduceNum()){
                produceProducts.setProduceStatus(2);
            }
            produceProductsMapper.updateById(produceProducts);

            schedulingOutSon.setType(2);
            schedulingOutSon.setUpdateTime(DateUtil.date());
            outSonMapper.updateById(schedulingOutSon);

            //判断生产单是否 从退货来
            Produce produce = produceMapper.selectById(schedulingOutSon.getProduceId());
            if (produce.getSource() == 1){
                //修改 退货产品中的 已处理数量
                Rejected rejected = rejectedMapper.selectById(produce.getRejectedId());
                QueryWrapper<RejectedProduct> wrapper1 = new QueryWrapper<>();
                wrapper1.lambda().eq(RejectedProduct::getRejectedId,rejected.getId())
                        .eq(RejectedProduct::getProductId,schedulingOutSon.getProductId());
                RejectedProduct rejectedProduct = rejectedProductMapper.selectOne(wrapper1);
                //修改已处理的数量
                int handleNum = rejectedProduct.getHandleNum() + schedulingOutSon.getSchedulingNum();
                rejectedProduct.setHandleNum( handleNum );
                rejectedProduct.setUpdateTime(DateUtil.date());
                rejectedProductMapper.updateById(rejectedProduct);
            }
        });

        List<Integer> ids = Stream.of(schedulingOut1.getProduceId().split(",")).map(Integer::valueOf).collect(Collectors.toList());
        ids.forEach(produceId->{
            equipmentService.updateProduceType(produceId);
        });

    }

    @Override
    public SchedulingOut selectOneDetail(Integer id){
        SchedulingOut schedulingOut = schedulingOutMapper.selectById(id);
        Vendor vendor = vendorMapper.selectById(schedulingOut.getSupplierId());
        schedulingOut.setCompanyName(vendor.getName());
        List<SchedulingOutSon> outSonList = outSonMapper.selectListByOutId(id);
        if (outSonList != null){
            schedulingOut.setSchedulingOutSonList(outSonList);
        }
        return schedulingOut;
    }

}
